<template>
  <div class="page">
    <img src="@/assets/back.png" class="close-icon" @click.stop="close" />
    <div class="qr-scanner qrcode-stream-wrapper" id="canvasbox">
      <video v-show="isVideo" class="qrcode-stream-camera"></video>
      <canvas id="canvas" class="qrcode-stream-camera" v-show="!isVideo"></canvas>
      <div class="scan-box">
        <div class="line"></div>
      </div>
    </div>
  </div>
</template>

<script>
import jsQR from "jsqr";
export default {
  data () {
    return {
      isVideo: true,
      code: "",
      videoEl: null
    };
  },
  mounted () {
    let src = this.GetQueryString('baseSrc')
    if (src) this.src = src
    let videoEl = document.querySelector("video");
    this.videoEl = videoEl
    this.onload();
  },
  methods: {
    GetQueryString (name) {
      var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
      var r = window.location.search.substr(1).match(reg);
      if (r != null) return unescape(r[2]);
      return null;
    },
    async onload () {
      const videoEl = this.videoEl
      let _this = this;
      if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
        console.log("不支持 enumerateDevices() .");
        alert('无法获取摄像功能')
      }
      const devices = (await navigator.mediaDevices.enumerateDevices()).filter(
        ({ kind }) => kind === "videoinput"
      );
      const rearCamera = devices[devices.length - 1];
      const constraints = {
        audio: false,
        video: {
          width: { min: 360, ideal: 640, max: 1920 },
          height: { min: 240, ideal: 480, max: 1080 },
          facingMode: "environment",
          deviceId: { exact: rearCamera.deviceId }
        }
      };
      navigator.mediaDevices.getUserMedia(constraints)
        .then(function (stream) {
          if (videoEl.srcObject !== undefined) {
            videoEl.srcObject = stream;
          } else if (videoEl.mozSrcObject !== undefined) {
            videoEl.mozSrcObject = stream;
          } else if (window.URL.createObjectURL) {
            videoEl.src = window.URL.createObjectURL(stream);
          } else if (window.webkitURL) {
            videoEl.src = window.webkitURL.createObjectURL(stream);
          } else {
            videoEl.src = stream;
          }
          videoEl.setAttribute("playsinline", true); // required to tell iOS safari we don't want fullscreen
          videoEl.onloadedmetadata = function () {
            videoEl.play()
            requestAnimationFrame(_this.tick)
          }
          // videoEl.play();
          // requestAnimationFrame(_this.tick);
        }).catch(function (err) {
          // alert('该浏览器不支持扫码,请更换浏览器')
          console.log(err.name + ": " + err.message)
        });
    },

    tick () {
      const videoEl = this.videoEl
      let canvasElement = document.getElementById("canvas");
      let canvas = canvasElement.getContext("2d");
      let canvasbox = document.getElementById("canvasbox");
      if (videoEl.readyState === videoEl.HAVE_ENOUGH_DATA) {
        canvasElement.hidden = false;
        canvasElement.height = videoEl.videoHeight;
        canvasElement.width = videoEl.videoWidth;
        canvas.drawImage(
          videoEl,
          0,
          0,
          videoEl.videoWidth,
          videoEl.videoHeight
        );
        let imageData = canvas.getImageData(
          canvasbox.getBoundingClientRect().left,
          canvasbox.getBoundingClientRect().top,
          canvasbox.offsetWidth,
          canvasbox.offsetHeight
        );
        let code = jsQR(imageData.data, imageData.width, imageData.height, {
          inversionAttempts: "attemptBoth",
        });
        if (code) {
          if (code.data) {
            if (this.src) {
              window.location.href = `${this.src}?code=${code.data}`;
            } else {
              document.write(code.data)
            }
          }
        }
      }
      requestAnimationFrame(this.tick);
    },

    close () {
      window.history.back();
    },
  },
  beforeDestroy () {
    this.videoEl = null
  }
};
</script>

<style >
.qrcode-stream-wrapper {
  width: 100%;
  height: 100%;
  position: relative;
  z-index: 0;
}

.page {
  width: 100vw;
  height: 100vh;
  overflow: hidden;
}
.close-box {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  text-align: left;
}
.qrcode-stream-camera {
  width: 100%;
  height: 100%;

  display: block;
  object-fit: cover;
}

.qr-scanner {
  background-image: linear-gradient(
      0deg,
      transparent 24%,
      rgba(32, 255, 77, 0.1) 25%,
      rgba(32, 255, 77, 0.1) 26%,
      transparent 27%,
      transparent 74%,
      rgba(32, 255, 77, 0.1) 75%,
      rgba(32, 255, 77, 0.1) 76%,
      transparent 77%,
      transparent
    ),
    linear-gradient(
      90deg,
      transparent 24%,
      rgba(32, 255, 77, 0.1) 25%,
      rgba(32, 255, 77, 0.1) 26%,
      transparent 27%,
      transparent 74%,
      rgba(32, 255, 77, 0.1) 75%,
      rgba(32, 255, 77, 0.1) 76%,
      transparent 77%,
      transparent
    );
  background-size: 3rem 3rem;
  background-position: -1rem -1rem;
  background-color: #111;
}

.qr-scanner .scan-box {
  width: 86vw;
  height: 70vh;
  max-height: 70vh;
  max-width: 90vh;
  position: absolute;
  left: 50%;
  top: 36%;
  transform: translate(-50%, -30%);
  overflow: hidden;
  z-index: 99;
}

.qr-scanner .line {
  height: 100%;
  width: 100%;
  background-image: linear-gradient(
    180deg,
    rgba(0, 255, 51, 0) 95%,
    #00ff33 120%
  );
  border-radius: 10px;
  transform: translateY(-100%);
  animation: radar-beam 2s infinite;
  animation-timing-function: cubic-bezier(0.53, 0, 0.43, 0.99);
  animation-delay: 1s;
}

@keyframes radar-beam {
  0% {
    transform: translateY(-100%);
  }

  100% {
    transform: translateY(0);
  }
}

.close-icon {
  height: 20px;
  width: 20px;
  position: fixed;
  left: 16px;
  top: 20px;
  z-index: 999;
}
</style>